<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.4"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Flow: flow::log::Msg_metadata Struct Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr id="projectrow">
  <td id="projectalign">
   <div id="projectname">Flow<span id="projectnumber">&#160;2.0.0</span>
   </div>
   <div id="projectbrief">Flow project: Public API.</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.4 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search",'Search','.html');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
  initMenu('',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="namespaceflow.html">flow</a></li><li class="navelem"><a class="el" href="namespaceflow_1_1log.html">log</a></li><li class="navelem"><a class="el" href="structflow_1_1log_1_1Msg__metadata.html">Msg_metadata</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="summary">
<a href="#pub-attribs">Public Attributes</a> &#124;
<a href="structflow_1_1log_1_1Msg__metadata-members.html">List of all members</a>  </div>
  <div class="headertitle"><div class="title">flow::log::Msg_metadata Struct Reference</div></div>
</div><!--header-->
<div class="contents">

<p>Simple data store containing all of the information generated at every logging call site by <a class="el" href="namespaceflow_1_1log.html" title="Flow module providing logging functionality.">flow::log</a>, except the message itself, which is passed to <a class="el" href="classflow_1_1log_1_1Logger.html#a934667f16dd6ca0841e521296ab3a6e2" title="Given a message and its severity, logs that message and possibly severity WITHOUT checking whether it...">Logger::do_log()</a> assuming <a class="el" href="classflow_1_1log_1_1Logger.html#ac8a2e7a33fe3fbc0c29ead62ed98c022" title="Given attributes of a hypothetical message that would be logged, return true if that message should b...">Logger::should_log()</a> had returned <code>true</code>.  
 <a href="structflow_1_1log_1_1Msg__metadata.html#details">More...</a></p>

<p><code>#include &lt;log.hpp&gt;</code></p>
<div class="dynheader">
Collaboration diagram for flow::log::Msg_metadata:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="structflow_1_1log_1_1Msg__metadata__coll__graph.svg" width="199" height="119"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
<center><span class="legend">[<a href="graph_legend.html">legend</a>]</span></center></div>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-attribs" name="pub-attribs"></a>
Public Attributes</h2></td></tr>
<tr class="memitem:a9d966ba8a227d1e7af587a8191ccf934"><td class="memItemLeft" align="right" valign="top"><a id="a9d966ba8a227d1e7af587a8191ccf934" name="a9d966ba8a227d1e7af587a8191ccf934"></a>
<a class="el" href="classflow_1_1log_1_1Component.html">Component</a>&#160;</td><td class="memItemRight" valign="bottom"><b>m_msg_component</b></td></tr>
<tr class="memdesc:a9d966ba8a227d1e7af587a8191ccf934"><td class="mdescLeft">&#160;</td><td class="mdescRight"><a class="el" href="classflow_1_1log_1_1Component.html" title="A light-weight class, each object storing a component payload encoding an enum value from enum type o...">Component</a> of message, as of this writing coming from either <a class="el" href="classflow_1_1log_1_1Log__context.html" title="Convenience class that simply stores a Logger and/or Component passed into a constructor; and returns...">Log_context</a> constructor or <a class="el" href="log_8hpp.html#ae4b5d4fdd2eb052615620879dd74af95" title="For the rest of the block within which this macro is instantiated, causes all FLOW_LOG_....">FLOW_LOG_SET_CONTEXT()</a>. <br /></td></tr>
<tr class="separator:a9d966ba8a227d1e7af587a8191ccf934"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a38ed0fc480839dd1c177fa5a8d59368a"><td class="memItemLeft" align="right" valign="top"><a class="el" href="namespaceflow_1_1log.html#a5c602384e6fe9d7642740ac2fae4ad04">Sev</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structflow_1_1log_1_1Msg__metadata.html#a38ed0fc480839dd1c177fa5a8d59368a">m_msg_sev</a></td></tr>
<tr class="memdesc:a38ed0fc480839dd1c177fa5a8d59368a"><td class="mdescLeft">&#160;</td><td class="mdescRight">Severity of message, typically determined by choice of macro (e.g., <a class="el" href="log_8hpp.html#a626c7dc4d3b4dc0b32a8aac8624d66bc" title="Logs a WARNING message into flow::log::Logger *get_logger() with flow::log::Component get_log_compone...">FLOW_LOG_WARNING()</a> vs.  <a href="structflow_1_1log_1_1Msg__metadata.html#a38ed0fc480839dd1c177fa5a8d59368a">More...</a><br /></td></tr>
<tr class="separator:a38ed0fc480839dd1c177fa5a8d59368a"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a5e7224fd18f1b9b2600508ac399687dd"><td class="memItemLeft" align="right" valign="top"><a class="el" href="namespaceflow_1_1util.html#ae4dc52186797094b3040379ff19124c9">util::String_view</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structflow_1_1log_1_1Msg__metadata.html#a5e7224fd18f1b9b2600508ac399687dd">m_msg_src_file</a></td></tr>
<tr class="memdesc:a5e7224fd18f1b9b2600508ac399687dd"><td class="mdescLeft">&#160;</td><td class="mdescRight">Pointer/length into static-storage string that would have come from built-in <code>__FILE__</code> macro which is auto-invoked by all <code>FLOW_LOG_*()</code> logging call sites.  <a href="structflow_1_1log_1_1Msg__metadata.html#a5e7224fd18f1b9b2600508ac399687dd">More...</a><br /></td></tr>
<tr class="separator:a5e7224fd18f1b9b2600508ac399687dd"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a2f17801fae328d1fdc070edc2578dd91"><td class="memItemLeft" align="right" valign="top"><a id="a2f17801fae328d1fdc070edc2578dd91" name="a2f17801fae328d1fdc070edc2578dd91"></a>
unsigned int&#160;</td><td class="memItemRight" valign="bottom"><b>m_msg_src_line</b></td></tr>
<tr class="memdesc:a2f17801fae328d1fdc070edc2578dd91"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy of integer that would have come from built-in <code>__LINE__</code> macro which is auto-invoked by all <code>FLOW_LOG_*()</code> logging call sites. <br /></td></tr>
<tr class="separator:a2f17801fae328d1fdc070edc2578dd91"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af7704a632434e7b52c43ab6047cf023b"><td class="memItemLeft" align="right" valign="top"><a id="af7704a632434e7b52c43ab6047cf023b" name="af7704a632434e7b52c43ab6047cf023b"></a>
<a class="el" href="namespaceflow_1_1util.html#ae4dc52186797094b3040379ff19124c9">util::String_view</a>&#160;</td><td class="memItemRight" valign="bottom"><b>m_msg_src_function</b></td></tr>
<tr class="memdesc:af7704a632434e7b52c43ab6047cf023b"><td class="mdescLeft">&#160;</td><td class="mdescRight">Analogous to <a class="el" href="structflow_1_1log_1_1Msg__metadata.html#a5e7224fd18f1b9b2600508ac399687dd" title="Pointer/length into static-storage string that would have come from built-in __FILE__ macro which is ...">m_msg_src_file</a> but coming from <code>__FUNCTION__</code>, not <code>__FILE__</code>. See <a class="el" href="structflow_1_1log_1_1Msg__metadata.html#a5e7224fd18f1b9b2600508ac399687dd" title="Pointer/length into static-storage string that would have come from built-in __FILE__ macro which is ...">m_msg_src_file</a> perf notes. <br /></td></tr>
<tr class="separator:af7704a632434e7b52c43ab6047cf023b"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a11e04fcee8409b76adb9aaa3108f90e1"><td class="memItemLeft" align="right" valign="top">std::chrono::system_clock::time_point&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structflow_1_1log_1_1Msg__metadata.html#a11e04fcee8409b76adb9aaa3108f90e1">m_called_when</a></td></tr>
<tr class="memdesc:a11e04fcee8409b76adb9aaa3108f90e1"><td class="mdescLeft">&#160;</td><td class="mdescRight">Time stamp from as close as possible to entry into the log call site (usually <code><a class="el" href="log_8hpp.html#a626c7dc4d3b4dc0b32a8aac8624d66bc" title="Logs a WARNING message into flow::log::Logger *get_logger() with flow::log::Component get_log_compone...">FLOW_LOG_WARNING()</a></code> or similar).  <a href="structflow_1_1log_1_1Msg__metadata.html#a11e04fcee8409b76adb9aaa3108f90e1">More...</a><br /></td></tr>
<tr class="separator:a11e04fcee8409b76adb9aaa3108f90e1"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a4588cf8c827944e5379c6ad1fd11d6db"><td class="memItemLeft" align="right" valign="top">std::string&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structflow_1_1log_1_1Msg__metadata.html#a4588cf8c827944e5379c6ad1fd11d6db">m_call_thread_nickname</a></td></tr>
<tr class="memdesc:a4588cf8c827944e5379c6ad1fd11d6db"><td class="mdescLeft">&#160;</td><td class="mdescRight">Thread nickname, as for <a class="el" href="classflow_1_1log_1_1Logger.html#a5600c71ccaa294650c7d34b596d90bf5" title="Sets or unsets the current thread&#39;s logging-worthy string name; optionally sets the OS thread name (s...">Logger::this_thread_set_logged_nickname()</a>, of the thread from which the log call was invoked; or an empty string if the thread had no such nickname set at the time.  <a href="structflow_1_1log_1_1Msg__metadata.html#a4588cf8c827944e5379c6ad1fd11d6db">More...</a><br /></td></tr>
<tr class="separator:a4588cf8c827944e5379c6ad1fd11d6db"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a278ef30d1bdceb9482c0aef097177c91"><td class="memItemLeft" align="right" valign="top"><a class="el" href="namespaceflow_1_1util.html#a0a4e7b2d3107bd630e0dc0c0b8f2e4de">util::Thread_id</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structflow_1_1log_1_1Msg__metadata.html#a278ef30d1bdceb9482c0aef097177c91">m_call_thread_id</a></td></tr>
<tr class="memdesc:a278ef30d1bdceb9482c0aef097177c91"><td class="mdescLeft">&#160;</td><td class="mdescRight">Thread ID of the thread from which the log call was invoked; or a default-constructed (no-thread) such thread ID if the thread has a nickname, meaning <code>!m_call_thread_nickname.empty()</code>.  <a href="structflow_1_1log_1_1Msg__metadata.html#a278ef30d1bdceb9482c0aef097177c91">More...</a><br /></td></tr>
<tr class="separator:a278ef30d1bdceb9482c0aef097177c91"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p >Simple data store containing all of the information generated at every logging call site by <a class="el" href="namespaceflow_1_1log.html" title="Flow module providing logging functionality.">flow::log</a>, except the message itself, which is passed to <a class="el" href="classflow_1_1log_1_1Logger.html#a934667f16dd6ca0841e521296ab3a6e2" title="Given a message and its severity, logs that message and possibly severity WITHOUT checking whether it...">Logger::do_log()</a> assuming <a class="el" href="classflow_1_1log_1_1Logger.html#ac8a2e7a33fe3fbc0c29ead62ed98c022" title="Given attributes of a hypothetical message that would be logged, return true if that message should b...">Logger::should_log()</a> had returned <code>true</code>. </p>
<p >User only need to worry about this when dealing with the internals of a <a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">Logger</a> implementation. Copying is to be avoided, as there are some non-trivial data stored here; though it is not too bad.</p>
<dl class="section warning"><dt>Warning</dt><dd>If changing the insides of <a class="el" href="structflow_1_1log_1_1Msg__metadata.html" title="Simple data store containing all of the information generated at every logging call site by flow::log...">Msg_metadata</a>, ensure free function <code>deep_copy(const Msg_metadata&amp;)</code> remains accurate.</dd></dl>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000023">Todo:</a></b></dt><dd>Add support in <a class="el" href="structflow_1_1log_1_1Msg__metadata.html" title="Simple data store containing all of the information generated at every logging call site by flow::log...">Msg_metadata</a> for a message ID which could more straightforwardly help the human log reader to map a log line to the originating log call site in source code. One approach, then, might be to output that message ID when available; else output <a class="el" href="structflow_1_1log_1_1Msg__metadata.html#a5e7224fd18f1b9b2600508ac399687dd" title="Pointer/length into static-storage string that would have come from built-in __FILE__ macro which is ...">m_msg_src_file</a>, <a class="el" href="structflow_1_1log_1_1Msg__metadata.html#a2f17801fae328d1fdc070edc2578dd91" title="Copy of integer that would have come from built-in __LINE__ macro which is auto-invoked by all FLOW_L...">m_msg_src_line</a>, <a class="el" href="structflow_1_1log_1_1Msg__metadata.html#af7704a632434e7b52c43ab6047cf023b" title="Analogous to m_msg_src_file but coming from __FUNCTION__, not __FILE__. See m_msg_src_file perf notes...">m_msg_src_function</a>; or maybe both. </dd></dl>
</div><h2 class="groupheader">Member Data Documentation</h2>
<a id="a278ef30d1bdceb9482c0aef097177c91" name="a278ef30d1bdceb9482c0aef097177c91"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a278ef30d1bdceb9482c0aef097177c91">&#9670;&nbsp;</a></span>m_call_thread_id</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="namespaceflow_1_1util.html#a0a4e7b2d3107bd630e0dc0c0b8f2e4de">util::Thread_id</a> flow::log::Msg_metadata::m_call_thread_id</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Thread ID of the thread from which the log call was invoked; or a default-constructed (no-thread) such thread ID if the thread has a nickname, meaning <code>!m_call_thread_nickname.empty()</code>. </p>
<p >The working assumption is that (1) both members are met for direct log output only and no other logic; and (2) the nickname is preferable when set, the thread ID being the fallback. (If this sounds meh, consider that it's entirely reasonable to make the nickname contain some nice info <em>and</em> the original thread ID as well in string form. However, mind the length &ndash; the Performance Note in <a class="el" href="structflow_1_1log_1_1Msg__metadata.html#a4588cf8c827944e5379c6ad1fd11d6db" title="Thread nickname, as for Logger::this_thread_set_logged_nickname(), of the thread from which the log c...">m_call_thread_nickname</a> doc header.) </p>

</div>
</div>
<a id="a4588cf8c827944e5379c6ad1fd11d6db" name="a4588cf8c827944e5379c6ad1fd11d6db"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a4588cf8c827944e5379c6ad1fd11d6db">&#9670;&nbsp;</a></span>m_call_thread_nickname</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">std::string flow::log::Msg_metadata::m_call_thread_nickname</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Thread nickname, as for <a class="el" href="classflow_1_1log_1_1Logger.html#a5600c71ccaa294650c7d34b596d90bf5" title="Sets or unsets the current thread&#39;s logging-worthy string name; optionally sets the OS thread name (s...">Logger::this_thread_set_logged_nickname()</a>, of the thread from which the log call was invoked; or an empty string if the thread had no such nickname set at the time. </p>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="structflow_1_1log_1_1Msg__metadata.html#a278ef30d1bdceb9482c0aef097177c91" title="Thread ID of the thread from which the log call was invoked; or a default-constructed (no-thread) suc...">m_call_thread_id</a></dd></dl>
<h3>Perf note</h3>
<p >Setting this involves an <code>std::string</code> copy; the cost of this is worth considering given that this is done for every single log call site, if the nickname is indeed set. See performance note in doc header of <a class="el" href="classflow_1_1log_1_1Logger.html#a5600c71ccaa294650c7d34b596d90bf5" title="Sets or unsets the current thread&#39;s logging-worthy string name; optionally sets the OS thread name (s...">Logger::this_thread_set_logged_nickname()</a> for the recommendation and details. (Long story short, if you keep it at N <code>char</code>s or fewer, the cost of a non-empty <a class="el" href="structflow_1_1log_1_1Msg__metadata.html#a4588cf8c827944e5379c6ad1fd11d6db" title="Thread nickname, as for Logger::this_thread_set_logged_nickname(), of the thread from which the log c...">m_call_thread_nickname</a> becomes equal to that of an empty one. N might be 15 in gcc 5.) </p>

</div>
</div>
<a id="a11e04fcee8409b76adb9aaa3108f90e1" name="a11e04fcee8409b76adb9aaa3108f90e1"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a11e04fcee8409b76adb9aaa3108f90e1">&#9670;&nbsp;</a></span>m_called_when</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">std::chrono::system_clock::time_point flow::log::Msg_metadata::m_called_when</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Time stamp from as close as possible to entry into the log call site (usually <code><a class="el" href="log_8hpp.html#a626c7dc4d3b4dc0b32a8aac8624d66bc" title="Logs a WARNING message into flow::log::Logger *get_logger() with flow::log::Component get_log_compone...">FLOW_LOG_WARNING()</a></code> or similar). </p>
<p ><code>std::chrono</code> is used instead of boost.chrono for certain internal output reasons in <a class="el" href="classflow_1_1log_1_1Ostream__log__msg__writer.html" title="Utility class, each object of which wraps a given ostream and outputs discrete messages to it adorned...">Ostream_log_msg_writer</a>. </p>

</div>
</div>
<a id="a38ed0fc480839dd1c177fa5a8d59368a" name="a38ed0fc480839dd1c177fa5a8d59368a"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a38ed0fc480839dd1c177fa5a8d59368a">&#9670;&nbsp;</a></span>m_msg_sev</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="namespaceflow_1_1log.html#a5c602384e6fe9d7642740ac2fae4ad04">Sev</a> flow::log::Msg_metadata::m_msg_sev</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Severity of message, typically determined by choice of macro (e.g., <a class="el" href="log_8hpp.html#a626c7dc4d3b4dc0b32a8aac8624d66bc" title="Logs a WARNING message into flow::log::Logger *get_logger() with flow::log::Component get_log_compone...">FLOW_LOG_WARNING()</a> vs. </p>
<p ><a class="el" href="log_8hpp.html#a325fdd4b5cf0be49b37d3b7b7c29070d" title="Logs an INFO message into flow::log::Logger *get_logger() with flow::log::Component get_log_component...">FLOW_LOG_INFO()</a>) at the call site; though it can also be supplied manually via <code>FLOW_LOG_WITH[OUT]_CHECKING()</code> macro arg. </p>

</div>
</div>
<a id="a5e7224fd18f1b9b2600508ac399687dd" name="a5e7224fd18f1b9b2600508ac399687dd"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a5e7224fd18f1b9b2600508ac399687dd">&#9670;&nbsp;</a></span>m_msg_src_file</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="namespaceflow_1_1util.html#ae4dc52186797094b3040379ff19124c9">util::String_view</a> flow::log::Msg_metadata::m_msg_src_file</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Pointer/length into static-storage string that would have come from built-in <code>__FILE__</code> macro which is auto-invoked by all <code>FLOW_LOG_*()</code> logging call sites. </p>
<p >Formally this should be the pointer/length representing the substring of <code>__FILE__</code> that you wish to be logged in its entirely, no more and no less. For example the pointer might be to the first character, the lengh equal to <code>strlen()</code>; or more practically it might be one past the right-most dir separator character (and the length decremented accordingly).</p>
<p >To be explicit: The underlying memory must never be deallocated, in that it should never have been allocated on the heap but in static storage.</p>
<h3>Perf notes</h3>
<p >We store a <a class="el" href="namespaceflow_1_1util.html#ae4dc52186797094b3040379ff19124c9" title="Commonly used char-based Basic_string_view. See its doc header.">util::String_view</a>, not a <code>const char*</code>, which means not only a pointer but a length is stored here internally. That's fine (we discuss trade-offs just below); it should barely affect the perf of copying <a class="el" href="structflow_1_1log_1_1Msg__metadata.html" title="Simple data store containing all of the information generated at every logging call site by flow::log...">Msg_metadata</a>. However the length must be initialized. To initialize it in the most optimized way, recognize that it will come from <code>__FILE__</code> which is really a string literal substituted by preprocessor; therefore the length can be obtained at compile time via <code>sizeof()</code>. Hence use the 2-arg <code>String_view</code> ctor which takes the pointer <em>and</em> the length instead of figuring the latter out via <code>strlen()</code> which is linear-time. Update: The <a class="el" href="namespaceflow_1_1util.html#ae4dc52186797094b3040379ff19124c9" title="Commonly used char-based Basic_string_view. See its doc header.">util::String_view</a> in use as of this writing declares the 1-arg ctor as <code>constexpr</code> which indicates it might be able to do the <code>strlen()</code> (or equivalent) at compile-time. Nevertheless, this feels (and I say this with some related experience) like something that may or may not actually be implemented by a given compiler. So it's probably safer (in terms of portability) to still follow the 2-arg ctor advice above.</p>
<p >If it is desired (as suggested in an example above) to represent a mere substring of that, then as long as the computation of the appropriate first character past index 0 satisfies <code>constexpr</code> requirements (meaning, it will be computed at compile time, not runtime) &ndash; as does the according decrement of the length &ndash; then you're still fine. If it is done at runtime, then that's a hit to perf, so avoid it if at all possible.</p>
<p >If indeed you do want ultimately to output a substring of <code>__FILE__</code>, then in order to guarantee or at least increase the chance of compile-time computation of that substring you should in fact do it as early as possible at the log call site as opposed to later/nearer the time of final output to device/whatever by <a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">Logger</a>. In other words in that case do try to set this value to the substring from the start; don't leave it to the <a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">Logger</a>.</p>
<h3>Perf rationale: Why not use <code>const char*</code> instead?</h3>
<p >(This is arguably very nitpicky anyway, but these objects are generated and passed around at every single log call site, so we should try to save every little bit.) Let's stipulate that the cost of storing (RAM; and copying) the length is negligible. The next concern is initializing the length; the above shows that's free in practice. Finally, when output to the final device/whatever occurs within <a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">Logger</a> impl, there are two possibilities of how it might realistically act. One, it might search for the NUL char anyway &ndash; in which case we've changed nothing perf-wise &ndash; as it copies for output purposes. Two, it might require the length of the string and hence use <code>String_view::size()</code> and then perform the copy; in that case we have saved a linear search. (For example, if the <a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">Logger</a> is printing to an <code>ostream</code>, then there exists an <code>operator&lt;&lt;(ostream, String_view)</code> that'd be automatically used and would of course use the saved length properly.) So, it's a win or at worst a tie. </p>

</div>
</div>
<hr/>The documentation for this struct was generated from the following file:<ul>
<li>log/<a class="el" href="log_8hpp.html">log.hpp</a></li>
</ul>
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Fri Mar 28 2025 22:55:32 for Flow by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4
</small></address>
</body>
</html>
